package com.kamistoat.meimeimall.common.taskEngine;

import lombok.Data;

import java.util.concurrent.TimeUnit;

/**
 * 任务引擎中，用于执行任务的执行器的抽象类。任何用于执行任务的执行器，都必须继承该抽象类。
 * 任务引擎从线程池中选出一个任务详情时，根据详情找到对应的执行器，交给该执行器进行处理。
 */
@Data
public abstract class AbstractEngineTaskExecutor {
    /**
     * 执行该任务的超时时间。如果超时，该次执行失败
     */
    protected int timeout;
    protected TimeUnit timeUnit;
    /**
     * 异常策略
     */
    protected FailedStrategyEnum failStrategy;
    /**
     * 重新投递的次数上限
     */
    protected int failTimesLimit;

    protected void invoke(EngineTaskDetail taskDetail) {
        try {
            invokeTask(taskDetail);
            continueTask(taskDetail);
        } catch (Exception exception) {
            if (failStrategy.equals(FailedStrategyEnum.REPOST) && taskDetail.getFailTimes() < failTimesLimit - 1) {
                taskDetail.setFailTimes(taskDetail.getFailTimes() + 1);
                taskDetail.getThreadPoolExecutor().submit(taskDetail);
            } else {
                abortTask(taskDetail, exception);
            }
        }
    }

    /**
     * 任务执行接口
     *
     * @param taskDetail 任务详情
     * @return T 任务返回值
     */
    protected abstract void invokeTask(EngineTaskDetail taskDetail);

    /**
     * 任务执行成功，继续接下来的流程
     *
     * @param taskDetail 任务详情
     */
    protected abstract void continueTask(EngineTaskDetail taskDetail);

    /**
     * 任务执行失败，且不进行重新投递，停止执行。
     *
     * @param taskDetail 任务详情
     */
    protected abstract void abortTask(EngineTaskDetail taskDetail, Exception exception);
}
